/**
Address editable input.
Internally value stored as {city: "Moscow", street: "Lenina", building: "15"}

@class address
@extends abstractinput
@final
@example
<a href="#" id="address" data-type="address" data-pk="1">awesome</a>
<script>
$(function(){
    $('#address').editable({
        url: '/post',
        title: 'Enter city, street and building #',
        value: {
            city: "Moscow", 
            street: "Lenina", 
            building: "15"
        }
    });
});
</script>
**/
(function ($) {
    "use strict";

    var Address = function (options) {
        this.countryList = options.countryList;
        this.stateList = options.stateList;
        this.cityList = options.cityList;
        this.init('address', options, Address.defaults);
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(Address, $.fn.editabletypes.abstractinput);

    $.extend(Address.prototype, {
        /**
        Renders input from tpl

        @method render() 
        **/
        render: function () {
            this.$input = this.$tpl.find('input');
            this.$list = this.$tpl.find('select');
            this.$list.empty();

            var fillCountry = function ($el, data) {
                if ($.isArray(data)) {
                    //Default Value
                    $el.append($('<option>', {
                        value: ""
                    }).text("--Select--"));

                    for (var i = 0; i < data.length; i++) {
                        if (data[i].children) {
                            $el.append(fillCountry($('<optgroup>', {
                                label: data[i].Name
                            }), data[i].children));
                        } else {
                            $el.append($('<option>', {
                                value: data[i].CountryId
                            }).text(data[i].Name));
                        }
                    }
                }
                return $el;
            };

            var fillState = function ($el, data) {
                if ($.isArray(data)) {

                    //Default Value
                    $el.append($('<option>', {
                        value: ""
                    }).text("--Select--"));

                    for (var i = 0; i < data.length; i++) {
                        if (data[i].children) {
                            $el.append(fillState($('<optgroup>', {
                                label: data[i].Name
                            }), data[i].children));
                        } else {
                            $el.append($('<option>', {
                                value: data[i].StateId
                            }).text(data[i].Name));
                        }
                    }
                }
                return $el;
            };

            var fillCity = function ($el, data) {
                if ($.isArray(data)) {

                    //Default Value
                    $el.append($('<option>', {
                        value: ""
                    }).text("--Select--"));

                    for (var i = 0; i < data.length; i++) {
                        if (data[i].children) {
                            $el.append(fillCity($('<optgroup>', {
                                label: data[i].Name
                            }), data[i].children));
                        } else {
                            $el.append($('<option>', {
                                value: data[i].CityId
                            }).text(data[i].Name));
                        }
                    }
                }
                return $el;
            };

            fillCountry(this.$list.filter('[name="country"]'), this.countryList);
            fillState(this.$list.filter('[name="state"]'), this.stateList);
            fillCity(this.$list.filter('[name="city"]'), this.cityList);
            
        },

        /**
        Default method to show value in element. Can be overwritten by display option.
        
        @method value2html(value, element) 
        **/
        value2html: function (value, element) {
            if (!value) {
                $(element).empty();
                return;
            }

            var cityText;
            $.each(this.cityList, function (i, v) {
                if (v.value == value.cityId) {
                    cityText = v.text.toUpperCase();
                }
            });

            var countryText;
            $.each(this.countryList, function (i, v) {
                if (v.value == value.countryId) {
                    countryText = v.text.toUpperCase();
                }
            });

            var stateText;
            $.each(this.stateList, function (i, v) {
                if (v.value == value.stateId) {
                    stateText = v.text.toUpperCase();
                }
            });

            var html = $('<div>').text(value.address1).html() +
                ' ' + $('<div>').text(value.address2).html() +
                ', ' + $('<div>').text(cityText).html() +
                ', ' + $('<div>').text(stateText).html() +
                ', ' + $('<div>').text(value.zip).html() +
                ', ' + $('<div>').text(countryText).html();

            $(element).html(html);
        },

        /**
        Gets value from element's html
        
        @method html2value(html) 
        **/
        html2value: function (html) {
            /*
              you may write parsing method to get value by element's html
              e.g. "Moscow, st. Lenina, bld. 15" => {city: "Moscow", street: "Lenina", building: "15"}
              but for complex structures it's not recommended.
              Better set value directly via javascript, e.g. 
              editable({
                  value: {
                      city: "Moscow", 
                      street: "Lenina", 
                      building: "15"
                  }
              });
            */
            return null;
        },

        /**
         Converts value to string. 
         It is used in internal comparing (not for sending to server).
         
         @method value2str(value)  
        **/
        value2str: function (value) {
            var str = '';
            if (value) {
                for (var k in value) {
                    str = str + k + ':' + value[k] + ';';
                }
            }
            return str;
        },

        /*
         Converts string to value. Used for reading value from 'data-value' attribute.
         
         @method str2value(str)  
        */
        str2value: function (str) {
            /*
            this is mainly for parsing value defined in data-value attribute. 
            If you will always set value by javascript, no need to overwrite it
            */
            return str;
        },

        /**
         Sets value of input.
         
         @method value2input(value) 
         @param {mixed} value
        **/
        value2input: function (value) {
            if (!value) {
                return;
            }
            this.$input.filter('[name="address1"]').val(value.address1);
            this.$input.filter('[name="address2"]').val(value.address2);
            this.$list.filter('[name="city"]').val(value.cityId);
            this.$list.filter('[name="state"]').val(value.stateId);
            this.$input.filter('[name="zip"]').val(value.zip);
            this.$list.filter('[name="country"]').val(value.countryId);

            //var cityList = value.cityList;
            //this.$list.filter('[name="city"]').append($("<option data-icon='fa-bolt'></option>").attr("value", "").text("--Select--"));
            //for (var i = 0; i < cityList.length; i++) {
            //    this.$list.filter('[name="city"]').append($("<option data-icon='fa-bolt'></option>").attr("value", cityList[i].cityId).text(cityList[i].CityName));
            //}
        },

        /**
         Returns value of input.
         
         @method input2value() 
        **/
        input2value: function () {
            return {
                address1: this.$input.filter('[name="address1"]').val(),
                address2: this.$input.filter('[name="address2"]').val(),
                cityId: this.$list.filter('[name="city"]').val(),
                stateId: this.$list.filter('[name="state"]').val(),
                zip: this.$input.filter('[name="zip"]').val(),
                countryId: this.$list.filter('[name="country"]').val()
            };
        },

        /**
        Activates input: sets focus on the first field.
        
        @method activate() 
       **/
        activate: function () {
            this.$input.filter('[name="address1"]').focus();
        },

        /**
         Attaches handler to submit form in case of 'showbuttons=false' mode
         
         @method autosubmit() 
        **/
        autosubmit: function () {
            this.$input.keydown(function (e) {
                if (e.which === 13) {
                    $(this).closest('form').submit();
                }
            });
        }
    });

    Address.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<div class="editable-address"><label><span>Address 1: </span><input type="text" name="address1" class="form-control input-small"></label></div>' +
            '<div class="editable-address"><label><span>Address 2: </span><input type="text" name="address2" class="form-control input-small"></label></div>' +
            '<div class="editable-address"><label><span>Country: </span><select name="country" class="bs-select1 form-control ddCountry" data-show-subtext="true"></select></label></div>' +
            '<div class="editable-address"><label><span>State: </span><select name="state" class="bs-select1 form-control ddState" data-show-subtext="true"></select></label></div>' +
            '<div class="editable-address"><label><span>City: </span><select name="city" class="bs-select1 form-control ddCity" data-show-subtext="true"></select></label></div>' +
             '<div class="editable-address"><label><span>zip: </span><input type="text" name="zip" class="form-control input-small"></label></div>',
        
        inputclass: '',
        countryList: [],
        stateList: [],
        cityList: []
    });

    $.fn.editabletypes.address = Address;

}(window.jQuery));